﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Text.RegularExpressions;

namespace FeiYang
{
    public class 技能_
    {
        public static Point[] 技能按键位置 = {
                                                                    new Point(1180, 660),
                                                                    new Point(1067,711),
                                                                    new Point(1086,616),
                                                                    new Point(1143,550),
                                                                    new Point(1230,547),
                                                                    new Point(971,707 ),
                                                                    new Point(994,611),
                                                                    new Point(1046,524),
                                                                    new Point(1132,455),
                                                                    new Point(1165,680 )
        };
        private int 火咒狂龙 { get; set; }
        private int 施毒冰咆哮冰旋风 { get; set; }
        private int 火墙流星 { get; set; }
        private int 召唤诱惑 { get; set; }
        private int 飞行 { get; set; }
        private int 替身 { get; set; }
        private int 隐身 { get; set; }
        private int 脱困 { get; set; }
        private int 普通攻击 { get; set; }
        private int 心灵召唤 { get; set; }

        public bool 可以施毒 = false;
        public bool 可以诅咒 = false;

        private Point 获取普通攻击()
        {
            return 技能按键位置[this.普通攻击];
        }
        private Point 获取心灵召唤()
        {
            return 技能按键位置[this.心灵召唤];
        }
        private Point 获取脱困()
        {
            if (this.脱困 != 0) return 技能按键位置[this.脱困];
            return new Point(-1, -1);
        }
        private Point 获取隐身()
        {
            if (this.隐身 != 0) return 技能按键位置[this.隐身];
            return new Point(-1, -1);
        }
        private Point 获取替身()
        {
            if (this.替身 != 0) return 技能按键位置[this.替身];
            return new Point(-1, -1);
        }
        private Point 获取主攻()
        {
            if (this.火咒狂龙 != 0) return 技能按键位置[this.火咒狂龙];
            return new Point(-1, -1);
        }
        private Point 获取辅攻()
        {
            if (this.施毒冰咆哮冰旋风 != 0) return 技能按键位置[this.施毒冰咆哮冰旋风];
            return new Point(-1, -1);
        }
        private Point 获取火墙()
        {
            if (this.火墙流星 != 0) return 技能按键位置[this.火墙流星];
            return new Point(-1, -1);
        }
        private Point 获取飞行()
        {
            if (this.飞行 != 0) return 技能按键位置[this.飞行];
            return new Point(-1, -1);
        }
        private Point 获取召唤()
        {
            if (this.召唤诱惑 != 0) return 技能按键位置[this.召唤诱惑];
            return new Point(-1, -1);
        }

        public void 使用心灵召唤()
        {
            var p = this.获取心灵召唤();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_200);
                // 屏幕中间
                键鼠_.左键单击(642, 374);
                其他_.延迟(其他_.时长_400);
                键鼠_.左键单击(p);
            }
            return;
        }

        public void 使用替身(Point 位置)
        {
            var p = this.获取替身();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_600);
                // 屏幕中间
                键鼠_.左键单击(位置);
                其他_.延迟(其他_.时长_400);
                键鼠_.左键单击(p);
            }
            return;
        }
        public void 使用隐身()
        {
            var p = this.获取隐身();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_600);
                // 屏幕中间
                键鼠_.左键单击(641, 411);
                其他_.延迟(其他_.时长_400);
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
            }
            return;
        }

        public void 使用火墙()
        {
            var p = this.获取火墙();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
            }
            return;
        }

        public void 使用召唤()
        {
            var p = this.获取召唤();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
            }
            return;
        }

        public void 使用飞行(Point 位置)
        {
            var p = this.获取飞行();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
                键鼠_.左键单击(位置);
                其他_.延迟(其他_.时长_600);
                键鼠_.左键单击(p);
            }
            return;
        }

        public void 使用脱困()
        {
            var p = this.获取脱困();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
            }
            return;
        }

        public void 使用辅攻()
        {
            var p = this.获取辅攻();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
            }
            return;
        }

        public void 使用辅攻(Point 位置)
        {
            var p = this.获取辅攻();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_200);
                键鼠_.左键单击(位置);
                其他_.延迟(其他_.时长_400);
                键鼠_.左键单击(p);
            }
            return;
        }
        public void 使用普通攻击()
        {
            键鼠_.左键单击(获取普通攻击());
            其他_.延迟(其他_.时长_400);
        }
        public void 使用主攻()
        {
            var p = this.获取主攻();
            if (p.X != -1)
            {
                键鼠_.左键单击(p);
                其他_.延迟(其他_.时长_400);
                return;
            }
            键鼠_.左键单击(获取普通攻击());
            其他_.延迟(其他_.时长_400);
            return;
        }
        public 技能_(技能设置_ 设置)
        {
            this.普通攻击 = 0;
            for (var i = 0; i < 设置.数据.Count; i++)
            {
                // // "无", "雷电术", "冰箭术", "狂龙紫电", "抗拒火环", "火墙", "冰咆哮",
                // // "冰旋风", "化身蝙蝠", "诱惑之光", "施毒术", "诅咒术", "治疗术",
                // // "群体治疗术", "幽冥火咒", "灵魂道符",
                // // "集体隐身术", "隐身术", "替身法符", "狮子吼",
                // // "召唤神兽", "强化骷髅术", "心灵召唤", "遁地"
                var 当前 = 设置.数据[i];
                if (当前 == "幽冥火咒" || 当前 == "灵魂道符" || 当前 == "雷电术" || 当前 == "狂龙紫电" || 当前 == "冰箭术")
                {
                    this.火咒狂龙 = i + 1;
                }
                else if (当前 == "施毒术" || 当前 == "诅咒术" || 当前 == "冰咆哮" || 当前 == "冰旋风" || 当前 == "五雷轰")
                {
                    if (当前 == "施毒术" || 当前 == "诅咒术")
                    {
                        this.可以施毒 = true;
                        if (当前 == "诅咒术")
                        {
                            this.可以诅咒 = true;
                        }
                    }
                    this.施毒冰咆哮冰旋风 = i + 1;
                }
                else if (当前 == "火墙" || 当前 == "流星火雨")
                {
                    this.施毒冰咆哮冰旋风 = i + 1;
                }
                else if (当前 == "诱惑之光" || 当前 == "赶尸")
                {
                    this.召唤诱惑 = i + 1;
                }
                else if (当前 == "遁地" || 当前 == "化身蝙蝠" || 当前 == "移形换影")
                {
                    this.飞行 = i + 1;
                }
                else if (当前 == "替身法符")
                {
                    this.替身 = i + 1;
                }
                else if (当前 == "隐身术" || 当前 == "集体隐身术")
                {
                    this.隐身 = i + 1;
                }
                else if (当前 == "狮子吼" || 当前 == "抗拒火环" || 当前 == "突斩" || 当前 == "野蛮")
                {
                    this.脱困 = i + 1;
                }
            }
        }
    }
    public enum 发现物品或怪物_
    {
       无_, 
       发现怪物_,
       发现物品_
    }

    public class 名称及序号_
    {
        public 名称及序号_(string 名称_ , int 序号_)
        {
            this.名称 = 名称_;
            this.序号 = 序号_;
        }

        public string 名称;
        public int 序号;
    }

    public class 怪物及点位_
    {
        public 怪物及点位_(怪物_ 怪物, Point 点位)
        {
            this.怪物 = 怪物;
            this.点位 = 点位;
        }

        public 怪物_ 怪物 { get;  set; }
        public Point 点位 { get;  set; }
    }
    public class 战斗_
    {
        public static Rectangle 发现物品监控区域 = Rectangle.FromLTRB(394, 551, 938, 580);
        public static Rectangle 聊天框监控区域 = Rectangle.FromLTRB(460, 697, 847, 718);

        public static Rectangle rt1 = Rectangle.FromLTRB(737, 282, 902, 303);
        public static Rectangle rt2 = Rectangle.FromLTRB(737, 327, 902, 348);
        public static Rectangle rt3 = Rectangle.FromLTRB(737, 372, 902, 393);
        public static Rectangle rt4 = Rectangle.FromLTRB(737, 417, 902, 438);
        public static Rectangle rt5 = Rectangle.FromLTRB(737, 462, 902, 483);
        private static string 正者表达式 = @"[:;：；]";

        private static string 宠物正则 = @"(弓箭守卫|大刀卫士|[\d()（）级])";

        public static void 手动战斗(挂机人物_ 人物)
        {
            // 战斗
            var 已经攻击 = 0;
            var 已经施毒 = !人物.技能.可以施毒;
            while (!其他_.cts.IsCancellationRequested)
            {
                if (战斗_.快速监控怪物列表())
                {
                    if (人物.职业 == "道士")
                    {
                        if (已经施毒)
                        {
                            if (!人物.技能.可以施毒)
                            {
                                if (!战斗_.有攻击目标())
                                {
                                    人物.输出("主技能攻击");
                                    人物.技能.使用主攻();
                                }
                            }
                            else if (已经攻击 < 5)
                            {
                                人物.输出("主技能攻击");
                                人物.技能.使用主攻();
                                已经攻击++;
                            }
                            已经施毒 = 战斗_.有红绿毒();
                        }
                        else if (!已经施毒)
                        {
                            人物.输出("辅技能攻击");
                            人物.技能.使用辅攻();
                            已经施毒 = 战斗_.有红绿毒();
                            已经攻击 = 0;
                        }
                        if (战斗_.发现物品或怪物() == 发现物品或怪物_.发现物品_)
                        {
                            已经攻击 = 0;
                            已经施毒 = !人物.技能.可以施毒;
                            var 还有物品 = false;
                            var i = 0;
                            do
                            {
                                i++;
                                UI_.点击捡物();
                                人物.输出("捡取 " + i + " 次");
                                还有物品 = 其他_.循环判断(() => 战斗_.发现物品或怪物() != 发现物品或怪物_.无_);
                            }
                            while (还有物品);
                        }
                    }
                    else
                    {
                        if (!战斗_.有攻击目标())
                        {
                            人物.输出("主技能攻击");
                            人物.技能.使用主攻();
                        }
                    }
                }
                return;
            }
            return;
        }

        public static 发现物品或怪物_ 发现物品或怪物()
        {
            var 内容 = 图像_.识别文字(发现物品监控区域);
            if (内容.Contains("方向"))
            {
                内容 = Regex.Replace(内容, 正者表达式, ":");
                var index = 内容.IndexOf("方");
                内容 = 内容.Substring(0, index);

                if (内容.Contains(":"))
                {
                    return 发现物品或怪物_.发现怪物_;
                }
                else
                {
                    return 发现物品或怪物_.发现物品_;
                }
            }
            return 发现物品或怪物_.无_;
        }

        public static bool 有红绿毒()
        {
            return 图像_.查找图片(Properties.Resources.有绿毒, Rectangle.FromLTRB(620, 88, 648, 115)).X != -1;
        }

        public static bool 有攻击目标()
        {
            return 图像_.查找图片(Properties.Resources.攻击目标, 544, 42, 585, 67, 0.8).X != -1;
        }

        public static bool 识别攻击目标血量是否为满血()
        {
            return 图像_.识别文字(656, 70, 700, 84).Contains("100");
        }

        public static bool 找到自己的镖车(挂机人物_ 人物)
        {
            var 人物姓名 = 人物.姓名;
            var 内容 = 图像_.识别文字(rt1);
            if (内容 != "")
            {
                var 找到 = 内部函数识别(rt1, new Point(790, 292));
                if (找到) return true;
                内容 = 图像_.识别文字(rt2);
                if (内容 != "")
                {
                    找到 = 内部函数识别( rt2, new Point(790, 337));
                    if (找到) return true;
                    内容 = 图像_.识别文字(rt3);
                    if (内容 != "")
                    {
                        找到 = 内部函数识别(rt3, new Point(790, 382));
                        if (找到) return true;
                        内容 = 图像_.识别文字(rt4);
                        if (内容 != "")
                        {
                            找到 = 内部函数识别(rt4, new Point(790, 427));
                            if (找到) return true;
                            内容 = 图像_.识别文字(rt5);
                            if (内容 != "")
                            {
                                找到 = 内部函数识别(rt5, new Point(790, 472));
                                if (找到) return true;
                            }
                        }
                    }
                }
            }
            return false;

            bool 内部函数识别(Rectangle 范围, Point 点击位置)
            {
                if (其他_.字符出现过(内容, "金币镖车"))
                {
                    键鼠_.左键单击(点击位置);
                    其他_.延迟(其他_.时长_400);
                    人物.技能.使用普通攻击();
                    if (其他_.字符出现过(内容, 人物.姓名))
                    {
                        键鼠_.左键单击(点击位置);
                        其他_.延迟(其他_.时长_400);
                        人物.技能.使用普通攻击();
                        return true;
                    }
                    var 结果 = 其他_.循环判断(() => 其他_.字符出现过(图像_.识别文字(范围), 人物.姓名), 4, 500);
                    if (结果)
                    {
                        键鼠_.左键单击(点击位置);
                        其他_.延迟(其他_.时长_400);
                        人物.技能.使用普通攻击();
                        return true;
                    }
                }
                else if (其他_.字符出现过(内容, 人物.姓名))
                {
                    键鼠_.左键单击(点击位置);
                    其他_.延迟(其他_.时长_400);
                    人物.技能.使用普通攻击();
                    if (其他_.字符出现过(内容, "金币镖车"))
                    {
                        键鼠_.左键单击(点击位置);
                        其他_.延迟(其他_.时长_400);
                        人物.技能.使用普通攻击();
                        return true;
                    }
                    var 结果 = 其他_.循环判断(() => 其他_.字符出现过(图像_.识别文字(范围), "金币镖车"), 4, 500); 
                    if (结果)
                    {
                        键鼠_.左键单击(点击位置);
                        其他_.延迟(其他_.时长_400);
                        人物.技能.使用普通攻击();
                        return true;
                    }
                }
                return false;
            }
        }

        public static bool 快速监控怪物列表()
        {
            var t1 = 图像_.识别文字(rt1);
            if (t1 != "")
            {
                if (!Regex.IsMatch(宠物正则, t1))
                {
                    return true;
                }
                t1 = 图像_.识别文字(rt2);
                if (t1 != "")
                {
                    if (!Regex.IsMatch(宠物正则, t1))
                    {
                        return true;
                    }
                    t1 = 图像_.识别文字(rt3);
                    if (t1 != "")
                    {
                        if (!Regex.IsMatch(宠物正则, t1))
                        {
                            return true;
                        }
                        t1 = 图像_.识别文字(rt4);
                        if (t1 != "")
                        {
                            if (!Regex.IsMatch(宠物正则, t1))
                            {
                                return true;
                            }
                            t1 = 图像_.识别文字(rt5);
                            if (t1 != "")
                            {
                                if (!Regex.IsMatch(宠物正则, t1))
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }

        public static bool 监控当前地图专注怪物列表(地图_ 地图, out 怪物及点位_ 怪物集点位)
        {
            if (地图.头目极品组.Count == 0)
            {
                怪物集点位 = null;
                return false;
            }
            var t1 = 图像_.识别文字(rt1).Trim();
            if (怪物列表_.具有怪物(t1) && 地图.头目极品组.Contains(怪物列表_.获取怪物(t1)))
            {
                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                return true;
            }
            t1 = 图像_.识别文字(rt2).Trim();
            if (怪物列表_.具有怪物(t1) && 地图.头目极品组.Contains(怪物列表_.获取怪物(t1)))
            {
                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                return true;
            }
            t1 = 图像_.识别文字(rt3).Trim();
            if (怪物列表_.具有怪物(t1) && 地图.头目极品组.Contains(怪物列表_.获取怪物(t1)))
            {
                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                return true;
            }
            t1 = 图像_.识别文字(rt4).Trim();
            if (怪物列表_.具有怪物(t1) && 地图.头目极品组.Contains(怪物列表_.获取怪物(t1)))
            {
                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                return true;
            }
            t1 = 图像_.识别文字(rt5).Trim();

            if (怪物列表_.具有怪物(t1) && 地图.头目极品组.Contains(怪物列表_.获取怪物(t1)))
            {
                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                return true;
            }
            怪物集点位 = null;
            return false;
        }


        public static bool 守点模式怪物监控列表(挂机人物_ 人物)
        {
            var t1 = 图像_.识别文字(rt1);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                键鼠_.左键单击(其他_.取中心(rt1));
                return true;
            }
            if (t1 != "" && 怪物列表_.具有怪物(t1))
            {
                return true;
            }

            t1 = 图像_.识别文字(rt2);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                键鼠_.左键单击(其他_.取中心(rt2));
                return true;
            }
            if (t1 != "" && 怪物列表_.具有怪物(t1))
            {
                return true;
            }
            t1 = 图像_.识别文字(rt3);

            if (人物.任务关注怪物.ContainsKey(t1))
            {
                键鼠_.左键单击(其他_.取中心(rt3));
                return true;
            }
            if (t1 != "" && 怪物列表_.具有怪物(t1))
            {
                return true;
            }
            t1 = 图像_.识别文字(rt4);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                键鼠_.左键单击(其他_.取中心(rt4));
                return true;
            }
            if (t1 != "" && 怪物列表_.具有怪物(t1))
            {
                return true;
            }
            return false;
        }

        public static bool 监控任务专注怪物列表(挂机人物_ 人物, out 怪物及点位_ 怪物集点位)
        {
            if (人物.任务关注怪物.Count == 0) {
                怪物集点位 = null;
                return false;
            }
            var t1 = 图像_.识别文字(rt1);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                人物.任务关注怪物.TryGetValue(t1, out var 怪物);
                怪物集点位 = new 怪物及点位_(怪物, 其他_.取中心(rt1));
                return true;
            }
            t1 = 图像_.识别文字(rt2);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                人物.任务关注怪物.TryGetValue(t1, out var 怪物);
                怪物集点位 = new 怪物及点位_(怪物, 其他_.取中心(rt2));
                return true;
            }
            t1 = 图像_.识别文字(rt3);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                人物.任务关注怪物.TryGetValue(t1, out var 怪物);
                怪物集点位 = new 怪物及点位_(怪物, 其他_.取中心(rt3));
                return true;
            }
            t1 = 图像_.识别文字(rt4);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                人物.任务关注怪物.TryGetValue(t1, out var 怪物);
                怪物集点位 = new 怪物及点位_(怪物, 其他_.取中心(rt4));
                return true;
            }
            t1 = 图像_.识别文字(rt5);
            if (人物.任务关注怪物.ContainsKey(t1))
            {
                人物.任务关注怪物.TryGetValue(t1, out var 怪物);
                怪物集点位 = new 怪物及点位_(怪物, 其他_.取中心(rt5));
                return true;
            }
            怪物集点位 = null;
            return false;
        }

        public static bool 监控怪物列表(out 怪物及点位_ 怪物集点位)
        {
            var t1 = 图像_.识别文字(rt1);
            if (t1 != "")
            {
                if (!Regex.IsMatch(宠物正则, t1))
                {
                    if (怪物列表_.具有怪物(t1))
                    {
                        怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt1));
                    }
                    else 怪物集点位 = null;
                    return true;
                }
                t1 = 图像_.识别文字(rt2);
                if (t1 != "")
                {
                    if (!Regex.IsMatch(宠物正则, t1))
                    {
                        if (怪物列表_.具有怪物(t1))
                        {
                            怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt2));
                        }
                        else 怪物集点位 = null;
                        return true;
                    }
                    t1 = 图像_.识别文字(rt3);
                    if (t1 != "")
                    {
                        if (!Regex.IsMatch(宠物正则, t1))
                        {
                            if (怪物列表_.具有怪物(t1))
                            {
                                怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt3));
                            }
                            else 怪物集点位 = null;
                            return true;
                        }
                        t1 = 图像_.识别文字(rt4);
                        if (t1 != "")
                        {
                            if (!Regex.IsMatch(宠物正则, t1))
                            {
                                if (怪物列表_.具有怪物(t1))
                                {
                                    怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt4));
                                }
                                else 怪物集点位 = null;
                                return true;
                            }
                            t1 = 图像_.识别文字(rt5);
                            if (t1 != "")
                            {
                                if (!Regex.IsMatch(宠物正则, t1))
                                {
                                    if (怪物列表_.具有怪物(t1))
                                    {
                                        怪物集点位 = new 怪物及点位_(怪物列表_.获取怪物(t1), 其他_.取中心(rt4));
                                    }
                                    else 怪物集点位 = null;
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            怪物集点位 = null;
            return false;
        }
    }
}
